home *** CD-ROM | disk | FTP | other *** search
Wrap
RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) NNNNaaaammmmeeee RWTValVirtualArray<T> - Rogue Wave library class SSSSyyyynnnnooooppppssssiiiissss #include <rw/tvrtarry.h> RWVirtualPageHeap* heap; RWTValVirtualArray<T> array(1000L, heap); DDDDeeeessssccccrrrriiiippppttttiiiioooonnnn This class represents a virtual array of elements of type TTTT of almost any length. Individual elements are brought into physical memory as needed basis. If an element is updated it is automatically marked as "dirty" and will be rewritten to the swapping medium. The swap space is provided by an abstract page heap which is specified by the constructor. Any number of virtual arrays can use the same abstract page heap. YYYYoooouuuu mmmmuuuusssstttt ttttaaaakkkkeeee ccccaaaarrrreeee tttthhhhaaaatttt tttthhhheeee ddddeeeessssttttrrrruuuuccccttttoooorrrr ooooffff tttthhhheeee aaaabbbbssssttttrrrraaaacccctttt ppppaaaaggggeeee hhhheeeeaaaapppp iiiissss nnnnooootttt ccccaaaalllllllleeeedddd bbbbeeeeffffoooorrrreeee aaaallllllll vvvviiiirrrrttttuuuuaaaallll aaaarrrrrrrraaaayyyyssss bbbbuuuuiiiilllltttt ffffrrrroooommmm iiiitttt hhhhaaaavvvveeee bbbbeeeeeeeennnn ddddeeeessssttttrrrrooooyyyyeeeedddd.... The class supports reference counting using a copy-on-write technique, so (for example) returning a virtual array by value from a function is as efficient as it can be. Be aware, however, that if the copy-on-write machinery finds that a copy must ultimately be made, then for large arrays this could take quite a bit of time. For efficiency, more than one element can (and should) be put on a page. The actual number of elements is equal to the page size divided by the element size, rounded downwards. Example: for a page size of 512 bytes, and an element size of 8, then 64 elements would be put on a page. The indexing operator (ooooppppeeeerrrraaaattttoooorrrr[[[[]]]]((((lllloooonnnngggg))))) actually returns an object of type RRRRWWWWTTTTVVVViiiirrrrttttuuuuaaaallllEEEElllleeeemmmmeeeennnntttt<<<<TTTT>>>>.... Consider this example: double d = vec[j]; vec[i] = 22.0; Assume that vvvveeeecccc is of type RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy<<<<ddddoooouuuubbbblllleeee>>>>.... The expression vvvveeeecccc[[[[jjjj]]]] will return an object of type RRRRWWWWTTTTVVVViiiirrrrttttuuuuaaaallllEEEElllleeeemmmmeeeennnntttt<<<<ddddoooouuuubbbblllleeee>>>>,,,, which will contain a reference to the element being addressed. In the first line, this expression is being used to initialize a ddddoooouuuubbbblllleeee. The class RRRRWWWWTTTTVVVViiiirrrrttttuuuuaaaallllEEEElllleeeemmmmeeeennnntttt<<<<TTTT>>>> contains a type conversion operator to convert itself to a TTTT, in this case a double. The compiler uses this to initialize dddd in the first line. In the second line, the expression vvvveeeecccc[[[[iiii]]]] is being used as an lvalue. In this case, the compiler uses the assignment operator for RRRRWWWWTTTTVVVViiiirrrrttttuuuuaaaallllEEEElllleeeemmmmeeeennnntttt<<<<TTTT>>>>.... This assignment operator recognizes that the expression is being used as an lvalue and PPPPaaaaggggeeee 1111 RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) automatically marks the appropriate page as "dirty," thus guaranteeing that it will be written back out to the swapping medium. Slices, as well as individual elements, can also be addressed. These should be used wherever possible as they are much more efficient because they allow a page to be locked and used multiple times before unlocking. The class TTTT must have: well-defined copy semantics (TTTT::::::::TTTT((((ccccoooonnnnsssstttt TTTT&&&&)))) or equiv.); well-defined assignment semantics (TTTT::::::::ooooppppeeeerrrraaaattttoooorrrr====((((ccccoooonnnnsssstttt TTTT&&&&)))) or equiv.). PPPPeeeerrrrssssiiiisssstttteeeennnncccceeee In addition, you must never take the address of an element. None EEEExxxxaaaammmmpppplllleeee In this example, a virtual vector of objects of type EEEErrrrssssaaaattttzzzzIIIInnnntttt is exercised. A disk-based page heap is used for swapping space. #include <rw/tvrtarry.h> #include <rw/rstream.h> #include <rw/diskpage.h> #include <stdlib.h> #include <stdio.h> struct ErsatzInt { char buf[8]; ErsatzInt(int i) { sprintf(buf, "%d", i); } friend ostream& operator<<(ostream& str, ErsatzInt& i) { str << atoi(i.buf); return str; } }; main() { RWDiskPageHeap heap; RWTValVirtualArray<ErsatzInt> vec1(10000L, &heap); for (long i=0; i<10000L; i++) vec1[i] = i; // Some compilers may need a cast here cout << vec1[100] << endl; // Prints "100" cout << vec1[300] << endl; // Prints "300" RWTValVirtualArray<ErsatzInt> vec2 = vec1.slice(5000L, 500L); cout << vec2.length() << endl; // Prints "500" cout << vec2[0] << endl; // Prints "5000"; return 0; } Program output: 100 300 500 PPPPaaaaggggeeee 2222 RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) PPPPuuuubbbblllliiiicccc CCCCoooonnnnssssttttrrrruuuuccccttttoooorrrrssss 5000 RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy<<<<TTTT>>>>(long size, RWVirtualPageHeap* heap); Construct a vector of length ssssiiiizzzzeeee. The pages for the vector will be allocated from the page heap given by hhhheeeeaaaapppp which can be of any type. RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy<<<<TTTT>>>>(const RWTValVirtualArray<T>& v); Constructs a vector as a copy of vvvv. The resultant vector will use the same heap and have the same length as vvvv. The actual copy will not be made until a write, minimizing the amount of heap allocations and copying that must be done. RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy<<<<TTTT>>>>(const RWTVirtualSlice<T>& sl); Constructs a vector from a slice of another vector. The resultant vector will use the same heap as the vector whose slice is being taken. Its length will be given by the length of the slice. The copy will be made immediately. PPPPuuuubbbblllliiiicccc DDDDeeeessssttttrrrruuuuccccttttoooorrrr ~~~~RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy<<<<TTTT>>>>(); Releases all pages allocated by the vector. PPPPuuuubbbblllliiiicccc OOOOppppeeeerrrraaaattttoooorrrrssss RWTValVirtualArray& ooooppppeeeerrrraaaattttoooorrrr====(const RWTValVirtualArray<T>& v); Sets self to a copy of vvvv. The resultant vector will use the same heap and have the same length as vvvv. The actual copy will not be made until a write, minimizing the amount of heap allocations and copying that must be done. void ooooppppeeeerrrraaaattttoooorrrr====(const RWTVirtualSlice<T>& sl); Sets self equal to a sssslllliiiicccceeee of another vector. The resultant vector will PPPPaaaaggggeeee 3333 RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) use the same heap as the vector whose slice is being taken. Its length will be given by the length of the slice. The copy will be made immediately. T ooooppppeeeerrrraaaattttoooorrrr====(const T& val); Sets all elements in self equal to vvvvaaaallll. This operator is actually quite efficient because it can work with many elements on a single page at once. A copy of vvvvaaaallll is returned. T ooooppppeeeerrrraaaattttoooorrrr[[[[]]]](long i) const; Returns a copy of the value at index iiii. The index iiii must be between zero and the length of the vector less one or an exception of type TTTTOOOOOOOOLLLL____LLLLOOOONNNNGGGGIIIINNNNDDDDEEEEXXXX will occur. RWTVirtualElement<T> ooooppppeeeerrrraaaattttoooorrrr[[[[]]]](long); Returns a reference to the value at index iiii. The results can be used as an lvalue. The index iiii must be between zero and the length of the vector less one or an exception of type TTTTOOOOOOOOLLLL____LLLLOOOONNNNGGGGIIIINNNNDDDDEEEEXXXX will occur. PPPPuuuubbbblllliiiicccc MMMMeeeemmmmbbbbeeeerrrr FFFFuuuunnnnccccttttiiiioooonnnnssss long lllleeeennnnggggtttthhhh() const; Returns the length of the vector. T vvvvaaaallll(long i) const; Returns a copy of the value at index iiii. The index iiii must be between zero and the length of the vector less one or an exception of type TTTTOOOOOOOOLLLL____LLLLOOOONNNNGGGGIIIINNNNDDDDEEEEXXXX will occur. void sssseeeetttt(long i, const T& v); Sets the value at the index iiii to vvvv. The index iiii must be between zero and the length of the vector less one or an exception of type TTTTOOOOOOOOLLLL____LLLLOOOONNNNGGGGIIIINNNNDDDDEEEEXXXX will occur. PPPPaaaaggggeeee 4444 RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) RRRRWWWWTTTTVVVVaaaallllVVVViiiirrrrttttuuuuaaaallllAAAArrrrrrrraaaayyyy((((3333CCCC++++++++)))) RWTVirtualSlice<T> sssslllliiiicccceeee(long start, long length); Returns a reference to a sssslllliiiicccceeee of self. The value ssssttttaaaarrrrtttt is the starting index of the slice, the value lllleeeennnnggggtttthhhh its extent. The results can be used as an lvalue. void rrrreeeesssshhhhaaaappppeeee(long newLength); Change the length of the vector to nnnneeeewwwwLLLLeeeennnnggggtttthhhh. If this results in the vector being lengthened then the value of the new elements is undefined. RWVirtualPageHeap* hhhheeeeaaaapppp() const; Returns a pointer to the heap from which the vector is getting its pages. PPPPaaaaggggeeee 5555